🏠↩︎ De vuelta a la página principal del curso


Inicio

🚀 Objetivo de la unidad

Que el estudiante sea capaz de importar y exportar bases de datos de y en diferentes formatos, así como ejecutar transformaciones básicas sobre estas utilizando data frames y el paquete data.table.


Nota importante: Los siguientes módulos prácticos son lineales.


2.1. Instalando y cargando paquetes

  • Instalando un paquete
# install.packages("ggplot2")
  • Cargando un paquete
library(ggplot2)

2.2. Creando data frames desde 0

Recuerde que un data frame se compone de vectores. En el siguiente bloque de código, se instancian dos vectores inicialmente,

x <- 1:10
y <- 3 + sin(x) 
df <- data.frame(x=x, sin_of_x=y) # Los vectores que compondrán un data frame deben ser del mismo tamaño


2.3. Conociendo a un data frame


La función head devuelve las primeras 6 observaciones (filas) de un data frame.

head(df)
##   x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585


La función tail devuelve las últimas 6 observaciones de un data frame.

tail(df)
##     x sin_of_x
## 5   5 2.041076
## 6   6 2.720585
## 7   7 3.656987
## 8   8 3.989358
## 9   9 3.412118
## 10 10 2.455979


Tanto head() como tail(), pueden recibir el argumento adicional n, que indicará cuántas observaciones devuelvolverá.

tail(df, n=2) # Imprime las dos últimas observaciones
##     x sin_of_x
## 9   9 3.412118
## 10 10 2.455979


La función colnames() devuelve los nombres de las variables de un data frame.

colnames(df)
## [1] "x"        "sin_of_x"


La función length() devuelve el número de vectores que componen a un data frame. El número de vectores será entonces igual al número de variables (columnas).

length(df)
## [1] 2


La función dim() devuelve un vector de tamaño 2 con las dimensiones del data frame. En la primer posición del vector, se devolverá el número de observaciones, y en la segunda posición, el número de variables.

dim(df)
## [1] 10  2


Recuerde que un data frame es la versión bidimensional de una lista.

typeof(df)
## [1] "list"


La función str() devuelve el tipo y tamaño de cada vector que compone a un data frame. A esto se le conoce como la “estructura” de un data frame.

str(df)
## 'data.frame':    10 obs. of  2 variables:
##  $ x       : int  1 2 3 4 5 6 7 8 9 10
##  $ sin_of_x: num  3.84 3.91 3.14 2.24 2.04 ...


La función summary() devuelve algunas de las medidas de dispersón de las variables numéricas de un data frame.

summary(df)
##        x            sin_of_x    
##  Min.   : 1.00   Min.   :2.041  
##  1st Qu.: 3.25   1st Qu.:2.522  
##  Median : 5.50   Median :3.277  
##  Mean   : 5.50   Mean   :3.141  
##  3rd Qu.: 7.75   3rd Qu.:3.795  
##  Max.   :10.00   Max.   :3.989


🤸 Ejercicio #1

  1. Cree un data frame que contenga el nombre, el primer apellido, la edad y su edad dentro de 10 años de diez personas. Nombre las columnas del data frame acorde.
  2. Instancie un objeto que guarde las dimensiones del data frame.
  3. Imprima la estructura del data frame para obtener las propiedades (tipo y tamaño) de todos los vectores que lo conforman.
  4. Obtenga el valor mínimo, el valor en el primer cuartil y el valor mediano de las variables numéricas del data frame.
  5. Calcule el promedio de las dos últimas columnas.


2.3. Extrayendo datos de un data frame

Recuerde cómo se veía nuestro data frame completo.

print(df)
##     x sin_of_x
## 1   1 3.841471
## 2   2 3.909297
## 3   3 3.141120
## 4   4 2.243198
## 5   5 2.041076
## 6   6 2.720585
## 7   7 3.656987
## 8   8 3.989358
## 9   9 3.412118
## 10 10 2.455979


Podemos extraer datos del data frame utilizando índices. En el siguiente caso, extraemos el dato de la variable #2 de la observación #1.

df[1, 2]
## [1] 3.841471


En el siguiente caso, extraemos el dato de la variable #2 de la observación #10.

df[10, 2]
## [1] 2.455979


Así mismo, podemos utilizar un vector de tamaño 1+n.

df[, 1:2]
##     x sin_of_x
## 1   1 3.841471
## 2   2 3.909297
## 3   3 3.141120
## 4   4 2.243198
## 5   5 2.041076
## 6   6 2.720585
## 7   7 3.656987
## 8   8 3.989358
## 9   9 3.412118
## 10 10 2.455979
df[c(3, 6), ]
##   x sin_of_x
## 3 3 3.141120
## 6 6 2.720585


Podemos extraer observaciones completas.

df[10, ]
##     x sin_of_x
## 10 10 2.455979


Podemos extraer el vector que compone una variable. En el siguiente caso, extraemos la variable #2.

df[, 2]
##  [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
##  [9] 3.412118 2.455979


También, podemos extraer el vector que compone una variable utilizando el nombre de la variable en lugar de su índice.

df[, "sin_of_x"]
##  [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
##  [9] 3.412118 2.455979


Finalmente, igual podemos extraer el vector que compone una variable utilizando $ + el nombre de la variable.

df$sin_of_x
##  [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
##  [9] 3.412118 2.455979

💡 He aquí la importancia de que los nombres de una variable no tengan espacios y utilicen guiones bajos.


Podemos extraer una variable conservando el formato de un data frame utilizando únicamente el índice o el nombre de la variable dentro de los corchetes:

df[2]
##    sin_of_x
## 1  3.841471
## 2  3.909297
## 3  3.141120
## 4  2.243198
## 5  2.041076
## 6  2.720585
## 7  3.656987
## 8  3.989358
## 9  3.412118
## 10 2.455979
df["sin_of_x"]
##    sin_of_x
## 1  3.841471
## 2  3.909297
## 3  3.141120
## 4  2.243198
## 5  2.041076
## 6  2.720585
## 7  3.656987
## 8  3.989358
## 9  3.412118
## 10 2.455979


Observe cómo la estructura cambia.

str(df[, 2]) # Este es un vector
##  num [1:10] 3.84 3.91 3.14 2.24 2.04 ...
str(df[2]) # Este es un data frame
## 'data.frame':    10 obs. of  1 variable:
##  $ sin_of_x: num  3.84 3.91 3.14 2.24 2.04 ...

La forma en que extraigamos el contenido de una variable, dependerá del uso que querramos darle. No existe una forma “correcta” de hacerlo.


De igual forma, podemos extraer variabes de un data frame con la función subset().

subset(df, select=sin_of_x) 
##    sin_of_x
## 1  3.841471
## 2  3.909297
## 3  3.141120
## 4  2.243198
## 5  2.041076
## 6  2.720585
## 7  3.656987
## 8  3.989358
## 9  3.412118
## 10 2.455979
subset(df, select=2)
##    sin_of_x
## 1  3.841471
## 2  3.909297
## 3  3.141120
## 4  2.243198
## 5  2.041076
## 6  2.720585
## 7  3.656987
## 8  3.989358
## 9  3.412118
## 10 2.455979


No siempre sabremos el índice de las observaciones que queremos extraer de un data frame. En la mayoría de los casos, queremos extraer observaciones con base en una o varias condiciones.

df[df[, 2] < 3, ]
##     x sin_of_x
## 4   4 2.243198
## 5   5 2.041076
## 6   6 2.720585
## 10 10 2.455979
df[df[, "sin_of_x"] < 3, ]
##     x sin_of_x
## 4   4 2.243198
## 5   5 2.041076
## 6   6 2.720585
## 10 10 2.455979
df[df$sin < 3, ]
##     x sin_of_x
## 4   4 2.243198
## 5   5 2.041076
## 6   6 2.720585
## 10 10 2.455979


2.4. Creando nuevas variables en un data frame

Para crear nuevas variables en un data frame, debemos asignar vectores nuevos vectores.

df$y <- 101:110 # Creamos una nueva variable asignándole la mu
print(df)
##     x sin_of_x   y
## 1   1 3.841471 101
## 2   2 3.909297 102
## 3   3 3.141120 103
## 4   4 2.243198 104
## 5   5 2.041076 105
## 6   6 2.720585 106
## 7   7 3.656987 107
## 8   8 3.989358 108
## 9   9 3.412118 109
## 10 10 2.455979 110
df$x_times_2 <- df$x * 2 
print(df)
##     x sin_of_x   y x_times_2
## 1   1 3.841471 101         2
## 2   2 3.909297 102         4
## 3   3 3.141120 103         6
## 4   4 2.243198 104         8
## 5   5 2.041076 105        10
## 6   6 2.720585 106        12
## 7   7 3.656987 107        14
## 8   8 3.989358 108        16
## 9   9 3.412118 109        18
## 10 10 2.455979 110        20
df$x_times_2_flag <- df$x_times_2 > 10
print(df)
##     x sin_of_x   y x_times_2 x_times_2_flag
## 1   1 3.841471 101         2          FALSE
## 2   2 3.909297 102         4          FALSE
## 3   3 3.141120 103         6          FALSE
## 4   4 2.243198 104         8          FALSE
## 5   5 2.041076 105        10          FALSE
## 6   6 2.720585 106        12           TRUE
## 7   7 3.656987 107        14           TRUE
## 8   8 3.989358 108        16           TRUE
## 9   9 3.412118 109        18           TRUE
## 10 10 2.455979 110        20           TRUE
df$x_cat <- ifelse(df$x == 2, yes="x igual a 2", no="x no es igual a dos")
print(df)
##     x sin_of_x   y x_times_2 x_times_2_flag               x_cat
## 1   1 3.841471 101         2          FALSE x no es igual a dos
## 2   2 3.909297 102         4          FALSE         x igual a 2
## 3   3 3.141120 103         6          FALSE x no es igual a dos
## 4   4 2.243198 104         8          FALSE x no es igual a dos
## 5   5 2.041076 105        10          FALSE x no es igual a dos
## 6   6 2.720585 106        12           TRUE x no es igual a dos
## 7   7 3.656987 107        14           TRUE x no es igual a dos
## 8   8 3.989358 108        16           TRUE x no es igual a dos
## 9   9 3.412118 109        18           TRUE x no es igual a dos
## 10 10 2.455979 110        20           TRUE x no es igual a dos


🤾 Ejercicio #2

Utilice el data frame construído en el ejercicio #2. 1. Instancie un nuevo objeto con un data frame que contenga únicamente la variable de nombre y de edad de aquellas personas con edad menor a la media de edad de todas las 10 personas. 2. En este segundo data frame, cree una nueva variable que indique la entidad federativa de cada uno de las personas. 3. Finalmente, en este segundo data frame, cree una nueva variable que indique si el nombre de la persona empieza con A, B o C de forma textual, es decir, con una cadena de caracteres.


2.5. Leyendo distintos tipos de archivos de datos

df_txt <- read.table("./data/plain_txt.txt", 
                 header = FALSE)
## Warning in read.table("./data/plain_txt.txt", header = FALSE): incomplete final
## line found by readTableHeader on './data/plain_txt.txt'


df_csv <- read.csv("./data/plain_csv.csv")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/plain_csv.csv'


df_delim <- read.delim("./data/txt_with_delim.txt", sep="$")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/txt_with_delim.txt'


library(readxl)
df_xlsx <- read_xlsx("./data/hoja_de_calculo.xlsx", sheet=1)


library(foreign)
# df_spss <- read.spss("example.sav",
#                      to.data.frame=TRUE,
#                      use.value.labels=FALSE) # SPSS data
# df_stata <- read.dta("example.dta") # Stata data


# file_url <- "https://data.cityofnewyork.us/api/views/kku6-nxdu/rows.csv?accessType=DOWNLOAD"
# download.file(file_url, destfile = "./data/demo_nyc.csv", method = "curl")
df_Demographic <- read.csv("./data/demo_nyc.csv")


2.6. Escribiendo distintos tipos de archivos de datos

Se recomienda ampliamente únicamente importar datos en formato csv.

# write.csv(df, file = ".data/cards.csv", row.names = FALSE)


🏄️ Ejercicio #3

  1. Entre a la página del INEGI y descargue los microdatos del ENIGH 2018 para con las características de las viviendas que habitan los integrantes del hogar (viviendas.*)
  2. Cree un nuevo proyecto de RStudio.
  3. Cree una nueva carpeta dentro del proyecto que se llame “datos” y ubique dentro de esta al archivo descomprimido que descargó.
  4. Cargue el conjunto de datos a R como un data frame.
  5. Extraiga un nuevo data frame con los encuestados que vivan en una vivienda en la que la mayor parte del material de los muros o paredes son de Tabique, ladrillo, block, piedra, cantera, cemento o concreto.
  6. Cree una nueva variable en este data frame que indice textualmente si la vivienda del encuestado tiene menos de dos cuartos.


2.7. Uniendo bases de datos.

print(df_delim)
##   Col1 Col2 Col3
## 1    1    2    3
## 2    4    5    6
## 3    7    8    9
## 4    a    b    c
print(df_xlsx)
## # A tibble: 5 x 2
##      x1    x2
##   <dbl> <dbl>
## 1     1     2
## 2     2     4
## 3     3     6
## 4     4     8
## 5     5    10
merged_df <- merge(x = df_delim,
                   y = df_xlsx,
                   by.x = "Col1",
                   by.y = "x1",
                   all.x = T)
print(merged_df)
##   Col1 Col2 Col3 x2
## 1    1    2    3  2
## 2    4    5    6  8
## 3    7    8    9 NA
## 4    a    b    c NA


🏄️ Ejercicio #4

  1. Entre a la página del INEGI y descargue los microdatos del ENIGH 2018 para con las características de los hogares que habitan los integrantes del hogar (hogares.*).
  2. Cree un nuevo proyecto de RStudio.
  3. Cree una nueva carpeta dentro del proyecto que se llame “datos” y ubique dentro de esta al archivo descomprimido que descargó,
  4. Cargue el conjunto de datos a R como un data frame.
  5. Una este conjunto de datos con el de características de las viviendas que habitan los integrantes del hogar (viviendas.*).